#include "GL/glew.h"
#include "LoadShader.h"
#include "utility.h"
#include "vmath.h"
#include "GLFW/glfw3.h"
#include <functional>
#include "UnfoldPicture.h"
#include "loadDDSTexture.h"

GLuint program = -1;
GLuint tex2D = -1;
UnfoldPicture* unflods[3]{ nullptr };

float _eyeEngel = 0, _eyeAspect = 60, _radius = 40;
Matrix4f _view, _projective;
Vector3f eyePosition;

static bool IsLeftbuttonDown = false;
static double PreMousePosX(0), PreMousePosY(0);
void mousePositionCallback(GLFWwindow* window, double xpos, double ypos)
{
	if (IsLeftbuttonDown)
	{
		int state = glfwGetKey(window, GLFW_KEY_LEFT_CONTROL);
		if (state == GLFW_PRESS)
		{
			float newAspect = _eyeAspect + 2.0f*(float)(ypos - PreMousePosY);
			if (newAspect > -10.f && newAspect < 80.f)
			{
				_eyeAspect = newAspect;
			}
		}
		else
		{
			float newRadius = _radius + 6.0f*(float)(ypos - PreMousePosY);
			if (newRadius > 10 && newRadius < 250)
			{
				_radius = newRadius;
			}
			_eyeEngel -= (float)(xpos - PreMousePosX) * 0.5f;
		}
	}
	PreMousePosX = xpos;
	PreMousePosY = ypos;
}

void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
	if (button == GLFW_MOUSE_BUTTON_LEFT)
	{
		IsLeftbuttonDown = action == GLFW_PRESS;
	}
}

float startTime = 1.f;
int currentUnfoldIndex = 0;

bool init()
{
	ShaderInfo si[] = { { GL_VERTEX_SHADER, "Shader.vert" },{ GL_FRAGMENT_SHADER, "Shader.frag" },{ GL_NONE, nullptr } };
	program = LoadShade(si);

	unflods[0] = UnfoldPicture::create(nullptr,new RollPath(60, 4, 0.1), 0.0);
	unflods[0]->setPosition(Vector3f(-30, 0, 0));

	unflods[1] = UnfoldPicture::create(new RollPath(30, 4, 0.1), new RollPath(30, 4, 0.1), 0.5);
	unflods[1]->setPosition(Vector3f(0, 0, 0));
	unflods[1]->setUnfoldTime(1.2f);

	unflods[2] = UnfoldPicture::create(new RollPath(60, 4, 0.1), nullptr, 1.0);
	unflods[2]->setPosition(Vector3f(30, 0, 0));


	vglImageData image;
	vglLoadImage("pic.dds", &image);
	tex2D = vglLoadTexture(&image);
	glBindTexture(GL_TEXTURE_2D, tex2D);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	return true;
}

void Display(double time)
{
	glClearColor(0.2f, 0.2f, 0.15f, 1.0); 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);


	float posX = _radius*sin(DEG2RAD_F(_eyeEngel)), posZ = _radius*cos((DEG2RAD_F(_eyeEngel)));
	eyePosition = Vector3f(posX, _eyeAspect, posZ);
	_view = Matrix4f::createLookAt(eyePosition, Vector3f(0.f, 0.f, 0.f), Vector3f(0.f, 1.f, 0.f));
	float ratioH_W = (float)getViewHeight() / (float)getViewWidth();
	_projective = Matrix4f::createFrustum(-5, 5, -5 * ratioH_W, 5 * ratioH_W, 6, 4000);

	float currentTime = (float)time - startTime;
	float unfoldTime = unflods[currentUnfoldIndex]->getUnfoldTime();
	// currentTime = 10;
	if (currentTime < 0.0001) {
		return;
	}

	if (currentTime > unfoldTime + 2) {
		startTime = (float)time + 1.f;
		currentUnfoldIndex = (currentUnfoldIndex + 1) % 3;
		return;
	}
	else if (currentTime > unfoldTime) {
		currentTime = unfoldTime;

	}

	float percentage = currentTime / unfoldTime;

	glUniform1i(300, 0);
	glBindTexture(GL_TEXTURE_2D, tex2D);
	unflods[currentUnfoldIndex]->draw(program, percentage, _projective * _view, eyePosition);

}

void onClose()
{	
	glDeleteTextures(1, &tex2D);
	glDeleteProgram(program);
	for (auto p : unflods) {
		delete p;
	}
}

